﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ReferralTracker.Models.Account;
using ReferralTracker.Data.Entities;
using ReferralTracker.BusinessObjects.Infrastructure;
using ReferralTracker.BusinessObjects;
using ReferralTracker.Data.Lookups;
using ReferralTracker.Helpers;
using System.Web.Configuration;

namespace ReferralTracker.Controllers {
    public class AccountController : Controller {

        [HttpPost]
        public ActionResult SignIn(string EMail, string Password) {
            var session = ReferralTrackerSession.Open();
            var auth = new Authentication();
            ActionResult result = HttpNotFound();

            if (auth.VerifyUser(EMail, Password)) {
                var account = new AccountManagement();
                var user = account.FindUserByEmail(EMail);

                switch (user.IdUserType) {
                    case UserType.User:
                        user.UserDetail.LastLogInIPAddress = WebInfo.GetIpAddress(Request);
                        result = RedirectToAction("UserPage", new { id = user.UserDetail.ReferralId });
                        break;
                    case UserType.Administrator:
                        result = RedirectToRoute(new { controller = "admin" });
                        break;
                }
                session.Commit();
            }

            session.Close();
            return result;
        }

        public ViewResult RegisterUser(string referralId) {
            var cookieName = WebConfigurationManager.AppSettings["CookieName"];
            var isPresent = false;

            if (Request.Cookies.AllKeys.Contains(cookieName)) {
                var cookie = Request.Cookies[cookieName];

                referralId = cookie.Value;
                isPresent = true;
            }

            ViewBag.IsCookiePresent = isPresent;
            ViewBag.ReferralId = referralId;
            return View();
        }

        [HttpPost]
        public ActionResult RegisterUser(RegisterUserModel model) {
            var clientIpAddress = WebInfo.GetIpAddress(Request);
            var user = new User() {
                EMail = model.Email,
                Password = model.Password,
                IdUserType = UserType.User,
                UserDetail = new UserDetail() {
                    FirstName = model.FirstName,
                    LastName = model.LastName,
                    SignUpIPAddress = clientIpAddress,
                    LastLogInIPAddress = clientIpAddress
                }
            };

            try {
                var session = ReferralTrackerSession.Open();
                var accounts = new AccountManagement();
                var referrer = accounts.GetUser(model.ParentReferralId);

                if (referrer != null) {
                    var proxy = new ReferralTrackerApiProxy(Request);
                    var referral = new Referral() {
                        User = referrer,
                        IdReferralType = ReferralType.RegistrationReferral,
                        ReferralLink = WebInfo.GetRegisterReferralUrl(Request, model.ParentReferralId),
                        ClientIPAddress = WebInfo.GetIpAddress(Request)
                    };
                    var apiResult = proxy.AddReferral(referral);

                    if (apiResult.Headers.Contains("Set-Cookie")) {
                        Response.Headers["Set-Cookie"] = apiResult.Headers.GetValues("Set-Cookie").First();
                    }
                    user.UserDetail.ParentReferralId = model.ParentReferralId;
                }

                accounts.RegisterUser(user);
                session.Commit();
                session.Close();
            }
            catch (Exception ex) {
                throw new Exception("Error encountered while adding a new user", ex);
            }

            return RedirectToAction("UserPage", new { id = user.UserDetail.ReferralId });
        }

        public ActionResult UserPage(string id) {
            var session = ReferralTrackerSession.Open();
            var accounts = new AccountManagement(session);
            var user = accounts.GetUser(id);
            ActionResult result = HttpNotFound();

            if (user != null) {
                var userDetail = user.UserDetail;
                var referralActivities = new List<UserReferralActivityModel>();
                var model = new UserEditModel() {
                    Id = user.Id,
                    FirstName = userDetail.FirstName,
                    LastName = userDetail.LastName,
                    EMail = user.EMail,
                    ReferralId = userDetail.ReferralId,
                    SignUpIPAddress = userDetail.SignUpIPAddress,
                    LastLogInIPAddress = userDetail.LastLogInIPAddress,
                    LastLoginDate = userDetail.LastLoginDate.ToString("MM/dd/yyyy hh:mm tt"),
                    RegisterReferralLink = WebInfo.GetRegisterReferralUrl(Request, userDetail.ReferralId),
                    ReferralActivities = referralActivities
                };

                foreach (var referral in user.Referrals.OrderByDescending(m => m.Date)) {
                    var refType = "";

                    switch (referral.IdReferralType) {
                        case ReferralType.LinkReferral:
                            refType = "Link Referral";
                            break;
                        case ReferralType.RegistrationReferral:
                            refType = "Registration Referral";
                            break;
                    }

                    var modelItem = new UserReferralActivityModel() {
                        Date = referral.Date.ToString("MM/dd/yyyy hh:mm tt"),
                        Link = referral.ReferralLink,
                        ReferralType = refType
                    };

                    referralActivities.Add(modelItem);
                }

                result = View(model);
            }

            session.Close();
            return result;
        }

        [HttpPost]
        public JsonResult VerifyCredentials(string email, string password) {
            var auth = new Authentication();
            var retVal = auth.VerifyUser(email, password);

            auth.Dispose();

            return Json(new { isvalid = retVal });
        }

        [HttpPost]
        public JsonResult UpdateUser(UserEditModel model) {
            var session = ReferralTrackerSession.Open();
            var account = new AccountManagement();
            var user = account.GetUser(model.Id);
            var success = false;
            var errMsg = "";

            try {
                if (user != null) {
                    user.EMail = model.EMail;
                    user.UserDetail.FirstName = model.FirstName;
                    user.UserDetail.LastName = model.LastName;

                    session.Commit();
                    success = true;
                }
            }
            catch (Exception ex) {
                errMsg = ex.Message;
            }

            session.Close();

            return Json(new { success = success, errorMessage = errMsg });
        }

        [HttpPost]
        public JsonResult UpdatePassword(int id, string oldPassword, string newPassword) {
            var session = ReferralTrackerSession.Open();
            var account = new AccountManagement();
            var user = account.GetUser(id);
            var success = false;
            var errMsg = "";

            try {
                if (user != null) {
                    if (user.Password == oldPassword) {
                        user.Password = newPassword;

                        session.Commit();
                        success = true;
                    }
                    else {
                        errMsg = "Invalid Current Password";
                    }
                }
            }
            catch (Exception ex) {
                errMsg = ex.Message;
            }

            session.Close();

            return Json(new { success = success, errorMessage = errMsg });
        }

        [HttpPost]
        public JsonResult IsValidReferralId(string referralId) {
            var account = new AccountManagement();
            var user = account.GetUser(referralId);

            account.Dispose();

            return Json(new { isvalid = (user != null) });
        }

    }
}
